﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnnamedPodcastLibrary;
using System.IO;
using System.Collections;
using System.Configuration;

namespace PodcastDownloader
{
    public partial class MainForm : Form
    {
        readonly Manager _manager;
        readonly BindingList<LogMessage> _log =  new BindingList<LogMessage>();
        readonly BindingSource _logBinder = new BindingSource();
        readonly BindingList<EpisodeModel> _sync = new BindingList<EpisodeModel>();
        readonly BindingSource _syncBinder = new BindingSource();
        readonly BindingList<DownloadMessage> _download = new BindingList<DownloadMessage>();
        readonly BindingSource _downloadBinder = new BindingSource();
        readonly BindingSource _podcastBinder = new BindingSource();
        readonly BindingList<FeedModel> _podcasts = new BindingList<FeedModel>();

        public MainForm()
        {
            InitializeComponent();
            this._syncStatusStrip.Visible = false;

            var appSettings = ConfigurationManager.AppSettings;

            //data dir:
            //Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),Application.ProductName)+Path.DirectorySeparatorChar
            this._manager = new Manager(appSettings["DataDirectory"],appSettings["StateFileName"])
            {
                SyncDirectory = appSettings["SyncDirectory"],
                FeedCheckMinutes = Convert.ToInt32(appSettings["FeedCheckMinutes"]),
                DownloadThreadIdleMilliseconds = Convert.ToInt32(appSettings["DownloadThreadIdleMilliseconds"]),
                ProcessThreadIdleMilliseconds = Convert.ToInt32(appSettings["ProcessThreadIdleMilliseconds"]),
                SkipVideoEpisodes = Convert.ToBoolean(appSettings["SkipVideoEpisodes"]),
            };

            this._logBinder.DataSource = this._log;
            this._logBinder.RaiseListChangedEvents = true;
            this._logGrid.DataSource = this._logBinder;

            this._syncBinder.DataSource = this._sync;
            this._syncBinder.RaiseListChangedEvents = true;
            this._syncGrid.DataSource = this._syncBinder;

            this._downloadBinder.DataSource = this._download;
            this._downloadBinder.RaiseListChangedEvents = true;
            this._downloadGrid.DataSource = this._downloadBinder;

            this._podcastBinder.DataSource = this._podcasts;
            this._podcastBinder.RaiseListChangedEvents = true;
            this._feedGrid.DataSource = this._podcastBinder;
            this._feedGrid.RowTemplate.MinimumHeight = 100;

            this._episodeGrid.DataSource = this._podcastBinder;
            this._episodeGrid.DataMember = "Episodes";

            this._manager.Changed += new EventHandler<ManagerChangedEventArgs>(_manager_Changed);
            this._manager.FeedInfoChanged += new EventHandler<FeedInfoChangedEventArgs>(_manager_FeedInfoChanged);
            this._manager.Start();
            this._manager.UpdateFeeds();
        }

        void _manager_FeedInfoChanged(object sender, FeedInfoChangedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new Action<object, FeedInfoChangedEventArgs>(this._manager_FeedInfoChanged), new object[]{sender, e});
                return;
            }
            if (e.Episode != null)
            {
               // if(this._podcasts.Con
            }
            if (e.Feed != null)
            {
                if (!this._podcasts.Contains(new FeedModel(e.Feed)))
                    this._podcasts.Add(new FeedModel(e.Feed));
                else
                {
                    this._podcasts.Remove(new FeedModel(e.Feed));
                    this._podcasts.Add(new FeedModel(e.Feed));
                }
            }
        }

        void _manager_Changed(object sender, ManagerChangedEventArgs e)
        {
            if(this.InvokeRequired)
            {
                this.BeginInvoke(new Action<object, ManagerChangedEventArgs>(this._manager_Changed),new object[]{sender, e});
                return;
            }

            //manage log tab
            if (e.Kind != ManagerEventKind.ManagerIdle)
            {
                this._log.Add(new LogMessage(e));
                if (this._log.Count > 5000)
                {
                    this._log.Clear();
                }
            }

        }

        private void _addPodcastFromClipboardMenuItem_Click(object sender, EventArgs e)
        {
            this._manager.AddFeed(new Uri(Clipboard.GetText()));
        }

        private void testToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            if (Clipboard.ContainsText()
                && Uri.IsWellFormedUriString(Clipboard.GetText(), UriKind.Absolute))
            {
                this._addPodcastFromClipboardMenuItem.Text =
                    string.Format("Add from Clipboard: '{0}'", Clipboard.GetText());
                this._addPodcastFromClipboardMenuItem.Visible = true;
            }
            else
            {
                this._addPodcastFromClipboardMenuItem.Visible = false;
            }
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if(components != null)
                    components.Dispose();

                this._manager.Changed -= this._manager_Changed;
                this._manager.FeedInfoChanged -= this._manager_FeedInfoChanged;

                if (this._manager != null)
                    this._manager.Dispose();
               
            }
            base.Dispose(disposing);
        }

        private void updateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this._manager.UpdateFeeds();
        }

        private void testToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        public static string ToMegaByte(long fileSize)
        {
            if(fileSize < 0)
                return "Unknown";
            const Int32 megabyte = 1048576;
            var mbTotal = Convert.ToDecimal((Decimal)fileSize / (Decimal)megabyte);
            return string.Format("{0:##.# 'MB';;0 'MB'}", mbTotal);
        }

        private void _importFromOpmlMenuItem_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dialog = new OpenFileDialog() {Multiselect = false })
            {
                if (dialog.ShowDialog() == DialogResult.OK)
                {
                    this._manager.ImportFeeds(dialog.FileName);
                }
            }
        }

        private void syncToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this._manager.Sync();
        }

        private void _feedGrid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            this.SetupFeedGrid();
        }

        void SetupFeedGrid()
        {
            //foreach (DataGridViewColumn column in this._feedGrid.Columns)
            //{

            //}
        }

        void SetupEpisodeGrid()
        {
            foreach (DataGridViewColumn column in this._episodeGrid.Columns)
            {
                if (column.Name == "Title"
                    || column.Name == "Description")
                    continue;
                column.Visible = false;
            }
        }

        private void _episodeGrid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            this.SetupEpisodeGrid();
        }

        private void exportSubscriptionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var saveAs = new SaveFileDialog() 
            { 
                Title = "Save feed export file as", 
                DefaultExt = "opml",
                Filter = "Feed Export File (*.opml)|*.opml",
                InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
            })
            {
                if (saveAs.ShowDialog(this) == DialogResult.OK)
                {
                    this._manager.ExportFeeds(saveAs.FileName);
                }
            }
        }

        private void downloadEpisodeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewCell cell in this._episodeGrid.SelectedCells)
            {
                var episode = (Episode)cell.OwningRow.DataBoundItem;
               // this._manager.DownloadEpisode(episode);
            }
        }

        private void _cancelDownloadButton_ButtonClick(object sender, EventArgs e)
        {
            this._manager.CancelCurrentDownload();
        }

        private void _syncStatusStripHideButton_Click(object sender, EventArgs e)
        {
            this._syncStatusStrip.Visible = false;
        }

        private void optionsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            
        }
    }
}
